//
// Created by tang on 23-3-4.
//

#include "application_ui.hpp"
#include <service/http_service.hpp>
#include "app/panels.hpp"
#include "application.hpp"
#include "core/assert.hpp"
#include "imgui.h"
#include "imgui_ext/ImGuiUtils.h"
#include "imgui_ext/imgui_ext.h"
#include "imgui_ext/imgui_notify.h"
#include "imgui_internal.h"
#include "plugin_mgr.hpp"
#include "services/pi_config_service.hpp"
#include "text/IconsFontAwesome6.h"

void PiInfoApp::render_ui (f32 delta)
{
    using namespace ImGui;

    [[maybe_unused]] UiData *ud = ui_data ();

    ImGuiViewport *viewport = GetMainViewport ();

    ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode | ImGuiDockNodeFlags_NoSplit;
    ImGuiWindowFlags   window_flags    = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;

    // fullscreen dockspace
    SetNextWindowPos (viewport->WorkPos);
    SetNextWindowSize (viewport->WorkSize);
    SetNextWindowViewport (viewport->ID);
    PushStyleVar (ImGuiStyleVar_WindowPadding, ImVec2{0,0});
    PushStyleVar (ImGuiStyleVar_WindowRounding, 0.0f);
    PushStyleVar (ImGuiStyleVar_WindowBorderSize, 0.0f);
    // window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
    // window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
    // window_flags |= ImGuiWindowFlags_NoBackground;
    window_flags |= ImGuiWindowFlags_NoNav;
    window_flags |= ImGuiWindowFlags_NoDecoration;
    window_flags |= ImGuiWindowFlags_NoBackground;
    window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus;

    Begin ("##DockspaceWin", nullptr, window_flags);

    PopStyleVar (3);

    ImGuiID dockSpaceId = ImGui::GetID ("MyDockSpace");
    if (DockBuilderGetNode (dockSpaceId) == nullptr)
    {
        // init layout
        DockBuilderRemoveNode (dockSpaceId);
        DockBuilderAddNode (dockSpaceId, ImGuiDockNodeFlags_DockSpace | ImGuiDockNodeFlags_CentralNode);
        DockBuilderSetNodePos (dockSpaceId, viewport->WorkPos);
        DockBuilderSetNodeSize (dockSpaceId, viewport->WorkSize);

        ImGuiID center = dockSpaceId;

        ImGuiID up;
        ImGuiID down = DockBuilderSplitNode (center, ImGuiDir_Down, 0.35f, nullptr, &up);

        ImGuiID left;
        ImGuiID right = DockBuilderSplitNode (up, ImGuiDir_Right, 0.75f, nullptr, &left);

        // DockBuilderCopyWindowSettings(const char *src_name, const char *dst_name)

        DockBuilderDockWindow (plugin_list_panel_name, left);
        DockBuilderDockWindow (plugin_content_panel_name, right);
        DockBuilderDockWindow (ui_test_panel_name, right);
        DockBuilderDockWindow (log_panel_name, down);

        DockBuilderFinish (dockSpaceId);
    }
    DockSpace (dockSpaceId, ImVec2 (0.0f, 0.0f), dockspace_flags);

    auto const plugin_setting_id = GetID (ICON_FA_PUZZLE_PIECE "程序设置");

    // 插件设置窗口
    CenterWindowPercent (0.85f);
    if (BeginPopupModal (ICON_FA_PUZZLE_PIECE "程序设置", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse))
    {
        PushStyleColor (ImGuiCol_ChildBg, 0);
        BeginChild ("##ContentArea", ImVec2 (0, -GetTextLineHeightWithSpacing () * 1.75f));
        PopStyleColor ();
        AlignTextToFramePadding ();
        ServiceManager::instance ()->request_service<pi_config_service> ()->render_config_ui ();
        EndChild ();
        if (int const clicked = BottomButtons ({ICON_FA_CHECK " 应用", ICON_FA_XMARK " 关闭"}); clicked >= 0)
        {
            switch (clicked)
            {
            case 0: ServiceManager::instance ()->request_service<pi_config_service> ()->close(true); break;
            case 1: ServiceManager::instance ()->request_service<pi_config_service> ()->close(false); break;
            }
            CloseCurrentPopup ();
        }
        EndPopup ();
    }

    if (BeginMenuBar ())
    {
        AlignTextToFramePadding();
        if (BeginMenu (ICON_FA_FILE_LINES " 文件"))
        {
            if (MenuItem (ICON_FA_RIGHT_FROM_BRACKET " 退出"))
            {
                quit ();
            }
            EndMenu ();
        }

        if (BeginMenu (ICON_FA_BORDER_TOP_LEFT " 视图设置")) {
            for (auto x = panels; x != panels + panel_count; ++x) {
                if (x->open) {
                    MenuItem (x->name, nullptr, x->open, true);
                } else {
                    MenuItem (x->name, nullptr, true, false);
                }
            }

            EndMenu();
        }

        if (BeginMenu (ICON_FA_GEARS " 设置"))
        {
            if (MenuItem (ICON_FA_PUZZLE_PIECE " 插件配置"))
            {
                // this line load config values
                ServiceManager::instance ()->request_service<pi_config_service> ()->open ();
                OpenPopup (plugin_setting_id);
            }
            EndMenu ();
        }

        // 显示帧数
        char buff[64] {0};
        ::snprintf (buff, sizeof (buff), "帧率: %.2f FPS / 帧时间: %.1f ms", GetIO ().Framerate, GetIO ().DeltaTime * 1000.f);
        SameLine (GetWindowContentRegionWidth () - CalcTextSize (buff).x - GetFontSize () * .5f);
        TextUnformatted (buff);

        EndMenuBar ();
    }
    End ();

    // draw panels
    for (auto x = panels; x != panels + panel_count; ++x) {
        if (!x->open || *(x->open)) {
            x->show();
        }
    }

// ShowDemoWindow ();
}

void PiInfoApp::setup_style (float scaling)
{
    auto &style = ImGui::GetStyle ();

    // Colors
    ImVec4 *colors                         = ImGui::GetStyle ().Colors;
    colors[ImGuiCol_Text]                  = ImVec4 (1.00f, 1.00f, 1.00f, 1.00f);
    colors[ImGuiCol_TextDisabled]          = ImVec4 (0.63f, 0.63f, 0.63f, 1.00f);
    colors[ImGuiCol_WindowBg]              = ImVec4 (0.15f, 0.22f, 0.30f, 1.00f);
    colors[ImGuiCol_ChildBg]               = ImVec4 (0.32f, 0.33f, 0.34f, 1.00f);
    colors[ImGuiCol_PopupBg]               = ImVec4 (0.16f, 0.24f, 0.23f, 1.00f);
    colors[ImGuiCol_Border]                = ImVec4 (0.22f, 0.41f, 0.72f, 0.58f);
    colors[ImGuiCol_BorderShadow]          = ImVec4 (0.00f, 0.00f, 0.00f, 0.00f);
    colors[ImGuiCol_FrameBg]               = ImVec4 (0.10f, 0.17f, 0.24f, 1.00f);
    colors[ImGuiCol_FrameBgHovered]        = ImVec4 (0.14f, 0.17f, 0.11f, 1.00f);
    colors[ImGuiCol_FrameBgActive]         = ImVec4 (0.18f, 0.18f, 0.04f, 1.00f);
    colors[ImGuiCol_TitleBg]               = ImVec4 (0.00f, 0.00f, 0.00f, 1.00f);
    colors[ImGuiCol_TitleBgActive]         = ImVec4 (0.05f, 0.15f, 0.29f, 1.00f);
    colors[ImGuiCol_TitleBgCollapsed]      = ImVec4 (0.00f, 0.00f, 0.00f, 0.51f);
    colors[ImGuiCol_MenuBarBg]             = ImVec4 (0.14f, 0.14f, 0.14f, 1.00f);
    colors[ImGuiCol_ScrollbarBg]           = ImVec4 (0.18f, 0.18f, 0.18f, 1.00f);
    colors[ImGuiCol_ScrollbarGrab]         = ImVec4 (0.50f, 0.50f, 0.50f, 1.00f);
    colors[ImGuiCol_ScrollbarGrabHovered]  = ImVec4 (0.60f, 0.60f, 0.60f, 1.00f);
    colors[ImGuiCol_ScrollbarGrabActive]   = ImVec4 (0.60f, 0.60f, 0.60f, 1.00f);
    colors[ImGuiCol_CheckMark]             = ImVec4 (0.93f, 0.93f, 0.93f, 1.00f);
    colors[ImGuiCol_SliderGrab]            = ImVec4 (0.17f, 0.54f, 0.51f, 1.000f);
    colors[ImGuiCol_SliderGrabActive]      = ImVec4 (0.42f, 0.57f, 0.09f, 1.00f);
    colors[ImGuiCol_Button]                = ImVec4 (0.42f, 0.57f, 0.09f, 1.00f);
    colors[ImGuiCol_ButtonHovered]         = ImVec4 (0.48f, 0.66f, 0.10f, 1.00f);
    colors[ImGuiCol_ButtonActive]          = ImVec4 (0.15f, 0.20f, 0.03f, 1.00f);
    colors[ImGuiCol_Header]                = ImVec4 (0.18f, 0.20f, 0.22f, 1.00f);
    colors[ImGuiCol_HeaderHovered]         = ImVec4 (0.10f, 0.40f, 0.75f, 0.78f);
    colors[ImGuiCol_HeaderActive]          = ImVec4 (0.26f, 0.59f, 0.98f, 1.00f);
    colors[ImGuiCol_Separator]             = ImVec4 (0.43f, 0.43f, 0.50f, 0.50f);
    colors[ImGuiCol_SeparatorHovered]      = ImVec4 (0.10f, 0.40f, 0.75f, 0.78f);
    colors[ImGuiCol_SeparatorActive]       = ImVec4 (0.10f, 0.40f, 0.75f, 1.00f);
    colors[ImGuiCol_ResizeGrip]            = ImVec4 (0.66f, 0.81f, 0.98f, 0.20f);
    colors[ImGuiCol_ResizeGripHovered]     = ImVec4 (0.76f, 0.87f, 1.00f, 0.67f);
    colors[ImGuiCol_ResizeGripActive]      = ImVec4 (0.83f, 0.91f, 1.00f, 0.95f);
    colors[ImGuiCol_Tab]                   = ImVec4 (0.37f, 0.42f, 0.42f, 0.86f);
    colors[ImGuiCol_TabHovered]            = ImVec4 (0.26f, 0.59f, 0.98f, 0.80f);
    colors[ImGuiCol_TabActive]             = ImVec4 (0.20f, 0.41f, 0.68f, 1.00f);
    colors[ImGuiCol_TabUnfocused]          = ImVec4 (0.07f, 0.10f, 0.15f, 0.97f);
    colors[ImGuiCol_TabUnfocusedActive]    = ImVec4 (0.14f, 0.26f, 0.42f, 1.00f);
    colors[ImGuiCol_DockingPreview]        = ImVec4 (0.26f, 0.59f, 0.98f, 0.70f);
    colors[ImGuiCol_DockingEmptyBg]        = ImVec4 (0.20f, 0.20f, 0.20f, 1.00f);
    colors[ImGuiCol_PlotLines]             = ImVec4 (0.61f, 0.61f, 0.61f, 1.00f);
    colors[ImGuiCol_PlotLinesHovered]      = ImVec4 (1.00f, 0.43f, 0.35f, 1.00f);
    colors[ImGuiCol_PlotHistogram]         = ImVec4 (0.90f, 0.70f, 0.00f, 1.00f);
    colors[ImGuiCol_PlotHistogramHovered]  = ImVec4 (1.00f, 0.60f, 0.00f, 1.00f);
    colors[ImGuiCol_TableHeaderBg]         = ImVec4 (0.19f, 0.19f, 0.20f, 1.00f);
    colors[ImGuiCol_TableBorderStrong]     = ImVec4 (0.31f, 0.31f, 0.35f, 1.00f);
    colors[ImGuiCol_TableBorderLight]      = ImVec4 (0.23f, 0.23f, 0.25f, 1.00f);
    colors[ImGuiCol_TableRowBg]            = ImVec4 (0.00f, 0.00f, 0.00f, 0.00f);
    colors[ImGuiCol_TableRowBgAlt]         = ImVec4 (1.00f, 1.00f, 1.00f, 0.06f);
    colors[ImGuiCol_TextSelectedBg]        = ImVec4 (0.26f, 0.59f, 0.98f, 0.35f);
    colors[ImGuiCol_DragDropTarget]        = ImVec4 (0.78f, 1.00f, 0.59f, 0.90f);
    colors[ImGuiCol_NavHighlight]          = ImVec4 (0.26f, 0.59f, 0.98f, 1.00f);
    colors[ImGuiCol_NavWindowingHighlight] = ImVec4 (1.00f, 1.00f, 1.00f, 0.70f);
    colors[ImGuiCol_NavWindowingDimBg]     = ImVec4 (0.80f, 0.80f, 0.80f, 0.20f);
    colors[ImGuiCol_ModalWindowDimBg]      = ImVec4 (0.80f, 0.80f, 0.80f, 0.35f);

    // Size
    style.FrameRounding     = 4.f * scaling;
    style.PopupRounding     = 4.f * scaling;
    style.ChildRounding     = 4.f * scaling;
    style.WindowRounding    = 4.f * scaling;
    style.GrabRounding      = 8.f * scaling;
    style.ScrollbarRounding = 8.f * scaling;
    style.WindowPadding     = {8.f * scaling, 8.f * scaling};
    style.FramePadding      = {6.f * scaling, 4.f * scaling};
    style.ItemSpacing       = {6.f * scaling, 4.f * scaling};
}
